package io.franzbecker.gradle.lombok.task

import io.franzbecker.gradle.lombok.AbstractIntegrationTest

/**
 * Integration tests for {@link DelombokTask}.
 */
class DelombokTaskIntegrationTest extends AbstractIntegrationTest {

    def "Calling delombok with --help throws no exception."() {
        given:
        buildFile << """
            import io.franzbecker.gradle.lombok.task.DelombokTask

            task delombokHelp(type: DelombokTask) {
                args "--help"
            }
        """.stripIndent()

        when:
        runBuild("delombokHelp")

        then:
        noExceptionThrown()
    }

    def "Delombok on directory produced proper output"() {
        given:
        createSourceForDelombok()

        and:
        buildFile << """
            dependencies {
                implementation 'org.slf4j:slf4j-api:1.7.12'
            }

            ${delombokTask()}
        """.stripIndent()

        when:
        runBuild("delombok")

        then:
        File file = new File(projectDir, "build/delombok/com/example/HelloWorld.java")
        file.exists()
        String contents = file.text
        !contents.contains("import lombok.Data")
        contents.contains("// Generated by delombok")
        contents.contains("public String getId() {")
    }

    def "Delombok classpath can be extended"() {
        given:
        def testFile = createFile("src/main/java/com/example/Example.java")
        testFile << """
            package com.example;

            import com.google.common.annotations.VisibleForTesting;

            public class Example {
            
                @VisibleForTesting
                protected void doSomething() {
                }
                
            }
        """.stripIndent()

        and:
        buildFile << """
            dependencies {
// TODO this doesn't make sense any more
                compileOnly "com.google.guava:guava:20.0" // 20.0 for Java 7 support
            }

            ${delombokTask("classpath += project.configurations.compileOnly")}
        """

        when:
        runBuild("delombok")

        then:
        File file = new File(projectDir, "build/delombok/com/example/Example.java")
        file.exists()
    }

    private void createSourceForDelombok() {
        def file = createFile("src/main/java/com/example/HelloWorld.java")
        file << """
            package com.example;

            import lombok.Data;
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;

            @Data
            public class HelloWorld {

                private static final Logger logger = LoggerFactory.getLogger(HelloWorld.class);

                private String id;

            }
        """.stripIndent()
    }

    private String delombokTask(String additionalConfig = "") {
        return """
            import io.franzbecker.gradle.lombok.task.DelombokTask

            task delombok(type: DelombokTask, dependsOn: compileJava) {
                ext.outputDir = file("\$buildDir/delombok")
                            
                outputs.dir(outputDir)
                sourceSets.main.java.srcDirs.each { 
                    inputs.dir(it)
                    args(it, "-d", outputDir)
                }

                $additionalConfig

                // Redirect the output of the process
                standardOutput = new ByteArrayOutputStream()
                errorOutput = new ByteArrayOutputStream()
                doLast {
                    // Fail the build if there was any error output
                    if (!errorOutput.toString().isEmpty()) {
                        throw new GradleException(errorOutput.toString())
                    }
                }
            }
        """
    }

}
